package cn.com.jdyun.controller;

import java.net.URLEncoder;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.servlet.http.HttpSession;

import cn.com.jdyun.util.MD5Util;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;

import cn.com.jdyun.dto.UserCredit;
import cn.com.jdyun.exception.BdexGatewayException;
import cn.com.jdyun.interceptor.Auth;
import cn.com.jdyun.pojo.Message;
import cn.com.jdyun.pojo.User;
import cn.com.jdyun.pojo.UserCandy;
import cn.com.jdyun.pojo.UserSec;
import cn.com.jdyun.pojo.UserWallet;
import cn.com.jdyun.service.MessageService;
import cn.com.jdyun.service.RefereeService;
import cn.com.jdyun.service.UserSecService;
import cn.com.jdyun.service.UserService;
import cn.com.jdyun.service.UserWalletService;
import cn.com.jdyun.util.CodeUtil;
import cn.com.jdyun.util.Constant;
import cn.com.jdyun.util.RedisUtil;
import cn.com.jdyun.util.WebConstants;
import cn.com.jdyun.util.reponse.Result;
import cn.com.jdyun.util.reponse.Status;

@RestController
public class UserCenterController {

    @SuppressWarnings("unused")
    private static final Logger logger = LoggerFactory.getLogger(UserCenterController.class);

    @Autowired
    private UserService userService;
    @Autowired
    private RefereeService refereeService;
    @Autowired
    private UserSecService userSecService;
    @Autowired
    private UserWalletService userWalletService;
    @Autowired
    private MessageService messageService;
    @Autowired
    RedisUtil redisUtil;

    /**
     * 用户个人信息
     *
     * @param session
     * @return
     * @throws Exception
     */
    @Auth
    @PostMapping("/UserCenter/getUserInfo")
    public Result getUserInfo(HttpSession session) throws Exception {
        UserCredit userCredit = (UserCredit) session.getAttribute(Constant.ACCOUNT_Mining);
        //获取最新的用户信息
        User user = userService.getById(userCredit.getId());
        user.setPassword(null);
        user.setPhone(WebConstants.shadowUserName(user.getPhone()));
        user.setEmail(WebConstants.shadowUserName(user.getEmail()));
        user.setNickName(WebConstants.shadowUserName(user.getNickName()));
        return Result.success(user);

    }

    /**
     * 用户修改个人信息
     *
     * @param user
     * @param session
     * @return
     * @throws Exception
     */
    @Auth
    @PostMapping("/UserCenter/updateUserInfo")
    public Result updateUserInfo(User user, HttpSession session) throws Exception {
        UserCredit userCredit = (UserCredit) session.getAttribute(Constant.ACCOUNT_Mining);
        user.setPassword(null);
        user.setReferee(null);
        user.setPhone(null);
        user.setEmail(null);
        if (StringUtils.isBlank(user.getHeadPic()) && StringUtils.isBlank(user.getNickName())) {
            return Result.create(Status.ILLEGAL_PARAMETER_VALUE, "parameter validate error", user);
        }
        if (StringUtils.isBlank(user.getHeadPic())) {
            user.setHeadPic(null);
        }
        if (StringUtils.isBlank(user.getNickName())) {
            user.setNickName(null);
        }
        user.setId(userCredit.getId());
        userService.saveOrUpdate(user);
        if (StringUtils.isNotBlank(user.getNickName())) {
            userCredit.setNickName(user.getNickName());
        }
        session.setAttribute(Constant.ACCOUNT_Mining, userCredit);
        user.setPhone(WebConstants.shadowUserName(user.getPhone()));
        user.setEmail(WebConstants.shadowUserName(user.getEmail()));
        user.setNickName(WebConstants.shadowUserName(user.getNickName()));
        return Result.success(user);
    }

    /**
     * 绑定邮箱
     *
     * @param email
     * @param code
     * @param session
     * @return
     * @throws Exception
     */
    @Auth
    @PostMapping("/UserCenter/bindEmail")
    public Result bindEmail(String email, String code, HttpSession session) throws Exception {
        UserCredit userCredit = (UserCredit) session.getAttribute(Constant.ACCOUNT_Mining);

        Object sessionUsername = null, sessionCode = null;
        sessionUsername = session.getAttribute(Constant.EMAIL);
        sessionCode = session.getAttribute(Constant.EMAIL_CODE);
        session.removeAttribute(Constant.EMAIL);
        session.removeAttribute(Constant.EMAIL_CODE);
        if (sessionUsername == null || !sessionUsername.equals(email) || sessionCode == null || !sessionCode.toString().equalsIgnoreCase(code)) {
            return Result.create(Status.ILLEGAL_PARAMETER_VALUE, "email code validate error", email);
        }

        User user = new User();
        user.setId(userCredit.getId());
        user.setEmail(email);
        userService.saveOrUpdate(user);
        user.setPhone(WebConstants.shadowUserName(user.getPhone()));
        user.setEmail(WebConstants.shadowUserName(user.getEmail()));
        user.setNickName(WebConstants.shadowUserName(user.getNickName()));
        return Result.success(user);
    }

    /**
     * 绑定手机号码
     *
     * @param phone
     * @param code
     * @param session
     * @return
     * @throws Exception
     */
    @Auth
    @PostMapping("/UserCenter/bindPhone")
    public Result bindPhone(String phone, String code, HttpSession session) throws Exception {
        UserCredit userCredit = (UserCredit) session.getAttribute(Constant.ACCOUNT_Mining);

        Object sessionUsername = null, sessionCode = null;
        sessionUsername = session.getAttribute(Constant.PHONE_NUMBER);
        sessionCode = session.getAttribute(Constant.PHONE_NUMBER_CODE);
        session.removeAttribute(Constant.PHONE_NUMBER);
        session.removeAttribute(Constant.PHONE_NUMBER_CODE);
        if (sessionUsername == null || !sessionUsername.equals(phone) || sessionCode == null || !sessionCode.toString().equalsIgnoreCase(code)) {
            return Result.create(Status.ILLEGAL_PARAMETER_VALUE, "phoneNumber code validate error", phone);
        }

        User user = new User();
        user.setId(userCredit.getId());
        user.setPhone(phone);
        userService.saveOrUpdate(user);
        
        user.setPhone(WebConstants.shadowUserName(user.getPhone()));
        user.setEmail(WebConstants.shadowUserName(user.getEmail()));
        user.setNickName(WebConstants.shadowUserName(user.getNickName()));
        return Result.success(user);
    }

    /**
     * 用户修改头像信息
     *
     * @param headPic 图像地址
     * @param session
     * @return
     * @throws Exception
     */
    @Auth
    @PostMapping("/UserCenter/updateUserHeadPic")
    public Result updateHeadPic(String headPic, HttpSession session) throws Exception {
        UserCredit userCredit = (UserCredit) session.getAttribute(Constant.ACCOUNT_Mining);
        User user = new User();
        user.setId(userCredit.getId());
        user.setHeadPic(headPic);
        userService.saveOrUpdate(user);
        userCredit.setHeadPic(headPic);
        session.setAttribute(Constant.ACCOUNT_Mining, userCredit);
        
        user.setPhone(WebConstants.shadowUserName(user.getPhone()));
        user.setEmail(WebConstants.shadowUserName(user.getEmail()));
        user.setNickName(WebConstants.shadowUserName(user.getNickName()));
        return Result.success(user);

    }

    /**
     * 修改密码
     *
     * @param oldpwd   原密码
     * @param password 新密码
     * @param repeat   二次确认密码
     * @param session
     * @return
     * @throws Exception
     */
    @Auth
    @PostMapping("/UserCenter/updateUserPwd")
    public Result updateUserPwd(String oldpwd, String password, String repeat, HttpSession session) throws Exception {
        UserCredit userCredit = (UserCredit) session.getAttribute(Constant.ACCOUNT_Mining);
        //检查密码的正误
        User user = new User();
        user.setId(userCredit.getId());
        user.setPassword(oldpwd);
        List<User> list = userService.selectBySelective(user);
        if (list == null || list.size() == 0) {
            return Result.create(Status.ILLEGAL_PARAMETER_VALUE, "oldpwd error", oldpwd);
        }
        if (!password.equals(repeat)) {
            return Result.create(Status.ILLEGAL_PARAMETER_VALUE, "repeat error", repeat);
        }
        //获取最新的用户信息
        user.setPassword(MD5Util.encode(password));
        user.setId(user.getId());
        userService.saveOrUpdate(user);
        
        user.setPassword(null);
        user.setPhone(WebConstants.shadowUserName(user.getPhone()));
        user.setEmail(WebConstants.shadowUserName(user.getEmail()));
        user.setNickName(WebConstants.shadowUserName(user.getNickName()));
        return Result.success(user);

    }

    /**
     * 用戶的推荐人
     *
     * @param session
     * @return
     * @throws Exception
     */
    @Auth
    @PostMapping("/UserCenter/getReferee")
    public Result getReferee(HttpSession session) throws Exception {
        UserCredit userCredit = (UserCredit) session.getAttribute(Constant.ACCOUNT_Mining);
        User user = refereeService.userReferee(userCredit.getId());
        user.setPassword(null);
        user.setPhone(WebConstants.shadowUserName(user.getPhone()));
        user.setEmail(WebConstants.shadowUserName(user.getEmail()));
        user.setNickName(WebConstants.shadowUserName(user.getNickName()));
        return Result.success(user);

    }

    /**
     * 用戶推荐的用户
     *
     * @param session
     * @return
     * @throws Exception
     */
    @Auth
    @PostMapping("/UserCenter/getReferees")
    public Result getReferees(HttpSession session) throws Exception {
        UserCredit userCredit = (UserCredit) session.getAttribute(Constant.ACCOUNT_Mining);
        List<User> users = refereeService.userReferees(userCredit.getId());
        if(users != null && users.size() > 0) {
        	for(User user: users) {
        		user.setPassword(null);
                user.setPhone(WebConstants.shadowUserName(user.getPhone()));
                user.setEmail(WebConstants.shadowUserName(user.getEmail()));
                user.setNickName(WebConstants.shadowUserName(user.getNickName()));
        	}
        }
        return Result.success(users);
    }

    /**
     * 发送手机或者邮箱验证码
     *
     * @param businessCode
     * @param session
     * @return
     * @throws Exception
     */
    @Auth
    @PostMapping("/UserCenter/vertify")
    public Result vertify(String businessCode, HttpSession session) throws Exception {
        UserCredit userCredit = (UserCredit) session.getAttribute(Constant.ACCOUNT_Mining);
        Result r = new Result();
        String code = CodeUtil.getCard();
        String userVertifyInfo = userCredit.getUsername();
        if (WebConstants.validEmail(userVertifyInfo)) {
            //发送邮件给用户
            userService.sendVerificationCodeToEmail(userVertifyInfo, code + "");

            session.setAttribute(Constant.EMAIL, userVertifyInfo);
            session.setAttribute(Constant.EMAIL_CODE, code + "");
            session.setAttribute(Constant.CODE_SEND_TIME, System.currentTimeMillis());
            r.setMsg("验证码已发送到您的邮箱,请注意查收");
            return r;
        } else if (WebConstants.validPhoneNumber(userVertifyInfo)) {
            //限制每天智能发5条信息
//            String nums = redisUtil.get(userVertifyInfo);
//            if (nums == null) {
//                redisUtil.set(userVertifyInfo, "1", 24 * 60 * 60);
//            } else {
//                int count = Integer.valueOf(nums);
//                if (count <= 5) {
//                    count++;
//                    redisUtil.set(userVertifyInfo, count + "", 24 * 60 * 60);
//                } else {
//                    return Result.create(Status.PHONE_CODE_SEND_LIMIT, "当日最多可发送5条短信", userVertifyInfo);
//                }
//            }
            //发送短信给用户
            String content = "";
            //发送短信给用户
            if (businessCode.equalsIgnoreCase(Constant.FINDTRADEPWD_CODE)) {
                content = "验证码：" + code + "，您的账号正在请求重置交易密码。10分钟内有效。";
            } else {
                throw new BdexGatewayException("获取验证码失败!");
            }
            userService.sendVerificationCodeToTelphone(URLEncoder.encode(content, "UTF-8"), "JUSTSend", userVertifyInfo, "", "", "", "");
            //保存当前信息，用于验证
            session.setAttribute(Constant.PHONE_NUMBER, userVertifyInfo);
            session.setAttribute(Constant.PHONE_NUMBER_CODE, code + "");
            session.setAttribute(Constant.CODE_SEND_TIME, System.currentTimeMillis());
            r.setMsg("验证码已发送到您的手机,请注意查收");
            return r;
        } else {
            return Result.fail(userVertifyInfo);
        }
    }

    /**
     * 修改支付密码
     *
     * @param loginpwd 登陆密码
     * @param password 新密码
     * @param repeat   二次确认密码
     * @param code     验证码
     * @param session
     * @return
     * @throws Exception
     */
    @Auth
    @PostMapping("/UserCenter/updateUserSecPwd")
    public Result updateUserSecPwd(String loginpwd, String password, String repeat, String code, HttpSession session) throws Exception {
        UserCredit userCredit = (UserCredit) session.getAttribute(Constant.ACCOUNT_Mining);
        //检查密码的正误
        User user = new User();
        user.setId(userCredit.getId());
        user.setPassword(loginpwd);
        List<User> list = userService.selectBySelective(user);
        if (list == null || list.size() == 0) {
            return Result.create(Status.ACCOUNT_PWD_ERROR, "loginpwd error", loginpwd);
        }

        //判断二次确认密码
        if (!password.equals(repeat)) {
            return Result.create(Status.ILLEGAL_PARAMETER_VALUE, "repeat error", repeat);
        }
        //判断验证码
        WebConstants.validEmailOrTelphone(userCredit.getUsername(), code, session, null);

        //修改用户支付密码
        userSecService.updateSecPwd(user.getId(), password);
        return Result.success(user.getId());

    }

    /**
     * 用户身份认证
     *
     * @param idCardNo
     * @param idCardName
     * @param idCardUp
     * @param idCardDown
     * @param session
     * @return
     * @throws Exception
     */
    @Auth
    @PostMapping("/UserCenter/certification")
    public Result certification(String idCardNo, String idCardName, @RequestParam(required = false) String idCardUp, @RequestParam(required = false) String idCardDown, HttpSession session) throws Exception {
        UserCredit userCredit = (UserCredit) session.getAttribute(Constant.ACCOUNT_Mining);

        if (!WebConstants.validIDCardNo(idCardNo)) {
            throw new BdexGatewayException("您提交的身份证号验证失败，请确认后提交");
        }
        UserSec userSec = new UserSec();
        userSec.setIdCardNo(idCardNo);
        userSec.setIdCardName(idCardName);
        userSec.setIdCardUp(idCardUp);
        userSec.setIdCardDown(idCardDown);
        userSec.setUserId(userCredit.getId());
        //保存实名认证信息
        userSecService.certification(userSec);
        //实名认证后，更新session信息
        userCredit.setSecFlag(userSec.getFlag());
        session.setAttribute(Constant.ACCOUNT_Mining, userCredit);
        
        return Result.success("实名认证信息提交成功，工作人员将尽快为您处理，请耐心等待");
    }


    /**
     * 用户身份认证信息
     *
     * @param session
     * @return
     * @throws Exception
     */
    @Auth
    @PostMapping("/UserCenter/userSec")
    public Result userSec(HttpSession session) throws Exception {

        UserCredit userCredit = (UserCredit) session.getAttribute(Constant.ACCOUNT_Mining);
        UserSec userSec = userSecService.queryByUserId(userCredit.getId());
        
        if(userSec == null) {
        	userSec = new UserSec();
        	userSec.setUserId(userCredit.getId());
        	userSec.setFlag(Byte.valueOf("0"));
        }
        userSec.setSecPassword(null);
        userSec.setIdCardNo(WebConstants.shadowIdCardName(userSec.getIdCardNo()));
        return Result.success(userSec);
    }

    /**
     * 获取用户的钱包
     *
     * @param session
     * @return
     * @throws Exception
     */
    @Auth
    @PostMapping("/UserCenter/userWallets")
    public Result userWallets(HttpSession session) throws Exception {

        UserCredit userCredit = (UserCredit) session.getAttribute(Constant.ACCOUNT_Mining);
        List<UserWallet> uws = userWalletService.queryUserWallets(userCredit.getId());

        return Result.success(uws);
    }

    /**
     * 获取用户的资产
     *
     * @param session
     * @return
     * @throws Exception
     */
    @Auth
    @PostMapping("/UserCenter/userAsset")
    public Result userAsset( String coinType, HttpSession session) throws Exception {

        UserCredit userCredit = (UserCredit) session.getAttribute(Constant.ACCOUNT_Mining);
        if (StringUtils.isEmpty(coinType)) {
           throw new BdexGatewayException("代币种类不能为空!");
        }
        UserWallet uw = userWalletService.queryByUserIdAndConiType(userCredit.getId(), coinType);

        return Result.success(uw);
    }

    /**
     * 获取用户消息
     *
     * @param session
     * @return
     * @throws Exception
     */
    @Auth
    @PostMapping("/UserCenter/messages")
    public Result messages(Byte flag, Integer pageNumber, Integer pageSize, HttpSession session) throws Exception {
        UserCredit userCredit = (UserCredit) session.getAttribute(Constant.ACCOUNT_Mining);
        PageHelper.startPage(pageNumber, pageSize);

        Page<Message> page = messageService.pageData(userCredit.getId(), flag);

        return Result.success(page.toPageInfo());
    }

    /**
     * 将消息设为已读
     *
     * @param messageId
     * @param session
     * @return
     * @throws Exception
     */
    @Auth
    @PostMapping("/UserCenter/readMessage")
    public Result readMessage(String messageId, HttpSession session) throws Exception {

        UserCredit userCredit = (UserCredit) session.getAttribute(Constant.ACCOUNT_Mining);
        messageService.readMessage(userCredit.getId(), messageId);

        return Result.success("");
    }

    /**
     * 删除消息
     *
     * @param messageId
     * @param session
     * @return
     * @throws Exception
     */
    @Auth
    @PostMapping("/UserCenter/delMessage")
    public Result delMessage(String messageId, HttpSession session) throws Exception {

        UserCredit userCredit = (UserCredit) session.getAttribute(Constant.ACCOUNT_Mining);
        messageService.delMessage(userCredit.getId(), messageId);

        return Result.success("");
    }

    /**
     * 全部设为已读
     *
     * @param messageId
     * @param session
     * @return
     * @throws Exception
     */
    @Auth
    @PostMapping("/UserCenter/readAllMessage")
    public Result readAllMessage(String messageId, HttpSession session) throws Exception {

        UserCredit userCredit = (UserCredit) session.getAttribute(Constant.ACCOUNT_Mining);
        messageService.readAllMessage(userCredit.getId());

        return Result.success("");
    }

    /**
     * 清空所有消息
     *
     * @param messageId
     * @param session
     * @return
     * @throws Exception
     */
    @Auth
    @PostMapping("/UserCenter/delAllMessage")
    public Result delAllMessage(String messageId, HttpSession session) throws Exception {

        UserCredit userCredit = (UserCredit) session.getAttribute(Constant.ACCOUNT_Mining);
        messageService.delAllMessage(userCredit.getId());

        return Result.success("");
    }

    /**
     * 邀请好友
     *
     * @param session
     * @return
     * @throws Exception
     */
    @Auth
    @PostMapping("/UserCenter/invite")
    public Result delAllMessage(HttpSession session) throws Exception {

        UserCredit userCredit = (UserCredit) session.getAttribute(Constant.ACCOUNT_Mining);
        Map<String, Object> result = new HashMap<>();
        //推荐码
        result.put("code", userCredit.getCode());
        //一级节点个数
        result.put("level1", refereeService.selectLevel1Amount(userCredit.getId()));
        //二级节点个数
        result.put("level2", refereeService.selectLevel2Amount(userCredit.getId()));

        UserCandy uc = userWalletService.queryUserCandyInfo(userCredit.getId());
        //获取的邀请糖果总数
        result.put("candyLocked", uc.getRewardInviteAll());

        //已释放的邀请糖果总数
        result.put("candyFree", uc.getFreeInviteAll());

        return Result.success(result);
    }
}
